<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>关于this</title>
</head>

<body>
    <script>
        let demo = {
            name: 'demo',
            first() {
                console.log(this.name);
            },
            two: () => {
                console.log(this);
            },
            three(arg1, arg2) {
                console.log(this.name + '的' + arg1 + arg2);
            }
        };
        let test = {
            name: 'test'
        };
        console.warn('指向demo对象(调用该方法的对象)');
        demo.first();
        console.warn('指向window  箭头函数不绑定this');
        demo.two();
        console.warn('通过apply改变demo.first内部的this指向');
        demo.first.apply(test);
        console.warn('通过call改变demo.first内部的this指向');
        demo.first.call(test);
        console.warn('通过bind改变demo.first内部的this指向');
        demo.first.bind(test)();
        console.warn('直接调用demo.three');
        demo.three('湖北省', '宜昌市');
        console.warn('调用 demo.three.call(test,"湖北省","宜昌市")');
        demo.three.call(test, '湖北省', '宜昌市');
        console.warn('调用 demo.three.apply(test,["湖北省","宜昌市"])');
        demo.three.apply(test, ['湖北省', '宜昌市']);
        console.warn('apply和call的区别：\n' +
            'call接受多个参数，以逗号隔开\n' +
            'apply以数组形式接受多个参数\n' +
            'call也可以一个参数接受的是一个数组\n' +
            'apply接受一个以上参数必须用数组'
        );
        console.warn('调用demo.three.bind(test,"湖北省","宜昌市")()');
        demo.three.bind(test, "湖北省", "宜昌市")();
        console.warn('调用demo.three.bind(test,["湖北省","宜昌市"])()');
        demo.three.bind(test, ["湖北省", "宜昌市"], "第三个")();
        console.warn('除过返回的是一个函数其他和call一致');
    </script>
</body>

</html>